package com.ldn.database.dao.service;

import com.ldn.database.dao.entities.BasicEntities;
import com.ldn.database.dao.entities.Page;
import com.mybatisflex.core.logicdelete.LogicDeleteManager;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.service.IService;
import com.mybatisflex.core.util.LambdaGetter;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * 扩展mybatisflex orm框架的IService接口
 *
 * @author 李大牛家的牛 (scafel@163.com)
 * @product serverless
 * @className BasicService
 * @createDate 2025/1/14 - 10:41
 * @description 扩展orm框架的IService接口
 * @see IService <a href="https://apidoc.gitee.com/mybatis-flex/mybatis-flex/com/mybatisflex/core/service/IService.html">IService</a>
 * @see BasicEntities
 **/
public interface BasicService<T extends BasicEntities> extends IService<T> {

    /**
     * 默认分页大小
     */
    int PAGE_SIZE = 20;

    /**
     * 根据字段获取一条数据
     *
     * @param column 字段
     * @param value 字段值
     * @return T 实体数据
     */
    default T getOneByField(LambdaGetter<T> column, Object value) {
        return getOneByField(column, value, false);
    }
    /**
     * 根据字段获取一条数据
     *
     * @param column 字段
     * @param value 字段值
     * @param validStatus 是否只获取status=1的数据
     * @return T 实体数据
     */
    default T getOneByField(LambdaGetter<T> column, Object value, boolean validStatus) {
        QueryWrapper query = QueryWrapper.create();
        query.eq(column, value);
        if (validStatus){
            query.eq("status", 1);
        }
        return getMapper().selectOneByQuery(query);
    }
    /**
     * 根据字段获取一条数据
     *
     * @param field 字段名
     * @param value 字段值
     * @return T 实体数据
     */
    default T getOneByField(String field, Object value) {
        return getOneByField(field, value, false);
    }
    /**
     * 根据字段获取一条数据
     *
     * @param field 字段名
     * @param value 字段值
     * @param validStatus 是否只获取status=1的数据
     * @return T 实体数据
     */
    default T getOneByField(String field, Object value, boolean validStatus) {
        QueryWrapper query = QueryWrapper.create();
        query.eq(field, value);
        if (validStatus){
            query.eq("status", 1);
        }
        return getMapper().selectOneByQuery(query);
    }
    /**
     * 根据字段获取一条数据
     *
     * @param fieldValues 字段值映射表
     * @return T 实体数据
     */
    default T getOneByField(Map<String, Object> fieldValues) {
        QueryWrapper query =QueryWrapper.create();
        fieldValues.forEach((k, v) -> {
            if (v != null){
                if (v instanceof String || v instanceof Number) {
                    query.eq(k, v);
                }
            }
        });
        return getMapper().selectOneByQuery(query);
    }
    /**
     * 根据code获取一条数据
     * @param code 数据编码
     * @return T 实体数据
     */
    default T getOneByCode(String code) {
        return getOneByField("code", code);
    }
    /**
     * 根据id获取一条数据
     * @param id 数据id
     * @return T 实体数据
     */
    default T getOneById(Serializable id) {
        return getOneByField("id", id);
    }
    /**
     * 根据id获取一条数据
     * <p>包括已经被逻辑删除的数据</p>
     * @param id 数据id
     * @return T 实体数据
     */
    default T getLogicOneById(Serializable id) {
        try{
            LogicDeleteManager.skipLogicDelete();
            return getOneByField("id", id);
        }finally {
            LogicDeleteManager.restoreLogicDelete();
        }
    }
    /**
     * 根据id集合获取列表数据
     * <p>包括已经被逻辑删除的数据</p>
     * @param ids 数据id
     * @return List<T> 实体数据
     */
    default List<T> listLogicByIds(Collection<? extends Serializable> ids){
        try{
            LogicDeleteManager.skipLogicDelete();
            return listByField("id", ids, false);
        }finally {
            LogicDeleteManager.restoreLogicDelete();
        }
    }
    /**
     * 根据code集合获取列表数据
     * <p>包括已经被禁用的数据</p>
     * @param codes 数据code
     * @return List<T> 实体数据
     */
    default List<T> listByCodes(List<String> codes) {
        return listByField("code", codes, false);
    }
    /**
     * 根据code集合获取列表数据
     *
     * @param codes 数据code
     * @param validStatus 是否只获取status=1的数据
     * @return List<T> 实体数据
     */
    default List<T> listByCodes(List<String> codes, boolean validStatus) {
        return listByField("code", codes, validStatus);
    }
    /**
     * 根据code集合获取列表数据
     * <p>包括已经被逻辑删除的数据</p>
     * <p>包括已经被禁用的数据</p>
     * @param codes 数据code
     * @return List<T> 实体数据
     */
    default List<T> listLogicByCodes(List<String> codes){
        return listLogicByCodes(codes, false);
    }
    /**
     * 根据code集合获取列表数据
     * <p>包括已经被逻辑删除的数据</p>
     *
     * @param codes 数据code
     * @param validStatus 是否只获取status=1的数据
     * @return List<T> 实体数据
     */
    default List<T> listLogicByCodes(List<String> codes, boolean validStatus){
        try{
            LogicDeleteManager.skipLogicDelete();
            return listByField("code", codes, validStatus);
        }finally {
            LogicDeleteManager.restoreLogicDelete();
        }
    }
    /**
     * 根据字段获取列表数据
     *
     * @param column 字段
     * @param value 字段值
     * @return List<T> 实体数据
     */
    default List<T> listByField(LambdaGetter<T> column, Object value) {
        QueryWrapper query =QueryWrapper.create();
        query.eq(column, value);
        return getMapper().selectListByQuery(query);
    }
    /**
     * 根据字段获取列表数据
     *
     * @param field 字段名
     * @param value 字段值
     * @param validStatus 是否只获取status=1的数据
     * @return List<T> 实体数据
     */
    default List<T> listByField(String field, Object value, boolean validStatus) {
        QueryWrapper query =QueryWrapper.create();
        query.eq(field, value);
        if (validStatus) {
            query.eq("status", 1);
        }
        return getMapper().selectListByQuery(query);
    }
    /**
     * 根据字段获取列表数据
     *
     * @param field 字段名
     * @param values 字段值
     * @param validStatus 是否只获取status=1的数据
     * @return List<T> 实体数据
     */
    default List<T> listByField(String field, Collection<? extends Serializable> values, boolean validStatus) {
        QueryWrapper query =QueryWrapper.create();
        query.in(field, values);
        if (validStatus) {
            query.eq("status", 1);
        }
        return getMapper().selectListByQuery(query);
    }
    default List<T> listByField(Map<String, Object> fieldValues) {
        if (fieldValues == null){
            return getMapper().selectAll();
        }
        QueryWrapper query =QueryWrapper.create();
        fieldValues.forEach((k, v) -> {
            if (v != null){
                if (v instanceof String || v instanceof Number) {
                    query.eq(k, v);
                }
            }
        });
        return getMapper().selectListByQuery(query);
    }
    /**
     * 根据字段获取列表数据
     * <p>包括已经被逻辑删除的数据</p>
     *
     * @param field 字段名
     * @param values 字段值
     * @param validStatus 是否只获取status=1的数据
     * @return List<T> 实体数据
     */
    default List<T> listLogicByField(String field, Collection<? extends Serializable> values, boolean validStatus) {
        try{
            LogicDeleteManager.skipLogicDelete();
            return listByField(field, values, validStatus);
        }finally {
            LogicDeleteManager.restoreLogicDelete();
        }
    }
    /**
     * 根据字段获取列表数据
     * <p>包括已经被逻辑删除的数据</p>
     *
     * @param field 字段名
     * @param value 字段值
     * @param validStatus 是否只获取status=1的数据
     * @return List<T> 实体数据
     */
    default List<T> listLogicByField(String field, Object value, boolean validStatus) {
        try{
            LogicDeleteManager.skipLogicDelete();
            return listByField(field, value, validStatus);
        }finally {
            LogicDeleteManager.restoreLogicDelete();
        }
    }
    /**
     * 保存一条数据
     * @param entity 要保存的实体数据
     * @return boolean 是否保存成功
     */
    boolean saveEntity(T entity);
    /**
     * 批量保存数据
     * @param entities 实体数据列表
     * @return boolean 是否保存成功
     */
    boolean saveBatchEntity(List<T> entities);
    /**
     * 批量更新数据
     * @param entities 实体数据列表
     * @return boolean 是否更新成功
     */
    boolean updateBatchEntity(List<T> entities);
    /**
     * 更新一条数据
     * @param entity 要更新的实体数据
     * @return boolean 是否更新成功
     */
    boolean updateEntity(T entity);
    /**
     * 逻辑删除一条数据
     * @param entity 要删除的实体数据
     * @return boolean 是否删除成功
     */
    boolean deleteEntity(T entity);
    /**
     * 批量逻辑删除数据
     * @param ids 要删除的id集合
     * @return boolean 是否删除成功
     */
    boolean deleteBatchEntity(List<? extends Serializable> ids);
    /**
     * 批量逻辑删除数据
     * @param entities 要删除的实体数据
     * @return boolean 是否删除成功
     */
    boolean deleteBatchEntities(List<T> entities);
    /**
     * 标热数据更新
     * @param entity 要标热的实体数据
     * @return boolean 是否成功
     */
    boolean hotEntity(T entity);
    /**
     * 状态数据更新
     * @param entity 要更新的实体数据
     * @return boolean 是否更新成功
     */
    boolean statusEntity(T entity);
    /**
     * 批量状态数据更新
     * @param entities 要更新的实体数据
     * @return boolean 是否更新成功
     */
    boolean statusBatchEntity(List<T> entities);
    /**
     * 受保护数据更新
     * @param entity 要更新的实体数据
     * @return boolean 是否更新成功
     */
    boolean protectEntity(T entity);
    /**
     * 分页查询
     * <p>用于使用自定义的分页类</p>
     * @param page 页码
     * @param size 每页数量
     * @param query 查询条件
     * @return Page<T> 分页实体数据 (包含总数量)
     */
    Page<T> page(Integer page, Integer size, QueryWrapper query);
    /**
     * 分页查询
     * <p>用于使用自定义的分页类， 默认返回{@see PAGE_SIZE}条数据</p>
     * @param page 页码
     * @return Page<T> 分页实体数据 (包含总数量)
     */
    default Page<T> pageEntity(Integer page) {
        return pageEntity(page, PAGE_SIZE, false);
    }
    /**
     * 分页查询
     * <p>用于使用自定义的分页类</p>
     * @param page 页码
     * @param size 每页数量
     * @return Page<T> 分页实体数据 (包含总数量)
     */
    default Page<T> pageEntity(Integer page, Integer size) {
        return pageEntity(page, size, false);
    }
    /**
     * 分页查询
     * <p>用于使用自定义的分页类</p>
     * @param page 页码
     * @param size 每页数量
     * @param validStatus 是否只获取status=1的数据
     * @return Page<T> 分页实体数据 (包含总数量)
     */
    Page<T> pageEntity(Integer page, Integer size, boolean validStatus);
    /**
     * 获取列表数据
     *
     * @return List<T> 实体数据
     */
    default List<T> listEntity(){
        return listEntity(false);
    }
    /**
     * 获取列表数据
     *
     * @param validStatus 是否只获取status=1的数据
     * @return List<T> 实体数据
     */
    List<T> listEntity(boolean validStatus);
    /**
     * 获取列表数据
     *
     * @param page 页码
     * @return List<T> 实体数据
     */
    default List<T> listEntity(Integer page){
        return listEntity(page, false);
    }
    /**
     * 获取列表数据
     *
     * @param page 页码
     * @param validStatus 是否只获取status=1的数据
     * @return List<T> 实体数据
     */
    default List<T> listEntity(Integer page, boolean validStatus){
        return pageEntity(page, PAGE_SIZE, validStatus).getRecords();
    }
}
